﻿using System.Runtime.CompilerServices;

namespace LINQPadLogParser
{
  internal enum CacheKey
  {
    ClientIP = 2,
    TimeTaken = 16,
    Uri = 22,
    DateTime = 23,
    ServerEndPoint = 24
  }

  internal static class Cache<T>
  {
    private static readonly Item[] Values = new Item[10];
// ReSharper disable StaticFieldInGenericType
    private static int _position;
// ReSharper restore StaticFieldInGenericType
    private static Item _last = new Item(0, default(CacheKey), default(T));

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    static Cache()
    {
      for (int i = 0; i < Values.Length; i++)
      {
        Values[i] = new Item(-1, default(CacheKey), default(T));
      }
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool TryGet(int id, CacheKey key, out T value)
    {
      if (_last.Id == id && _last.Key == key)
      {
        value = _last.Value;
        return true;
      }
      foreach (Item v in Values)
      {
        if (v.Id == id && key == v.Key)
        {
          value = v.Value;
          return true;
        }
      }
      value = default(T);
      return false;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void Set(int id, CacheKey key, T value)
    {
      Item v = Values[_position];
      Values[_position] = _last;
      v.Id = id;
      v.Key = key;
      v.Value = value;
      _last = v;
      _position = (_position + 1)%Values.Length;
    }

    private sealed class Item
    {
      public int Id;

      public CacheKey Key;
      public T Value;

      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public Item(int id, CacheKey key, T value)
      {
        Id = id;
        Key = key;
        Value = value;
      }
    }
  }
}